package _general.problem;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import _general.ObjectInterface;
import _general.SortObject;
import _general.TestInterface;

public abstract class SortAlgorithm implements TestInterface{

	private String name = "";
	private List<ObjectInterface> elementList;
	
	public SortAlgorithm() {
	}
	
	public SortAlgorithm(List<ObjectInterface> elementList) {
		this.elementList = elementList;
	}
	
	@Override
	public void createInitialList(String preSort, int size) throws Exception {
		this.elementList = new ArrayList<ObjectInterface>();
		
		if (preSort.toLowerCase().equals("random")) {
			throw new IllegalArgumentException("Wrong call for random presortion, no random seed specified.");
		} else if(preSort.toLowerCase().equals("ascending")){
		
			for (int i = 0; i < size; i++) {
				SortObject nextObject = new SortObject();
				nextObject.setId(i);
				elementList.add(nextObject);
			}
		} else if(preSort.toLowerCase().equals("descending")){
			for (int i = 0; i < size ; i++) {
				SortObject nextObject = new SortObject();
				nextObject.setId(size - i - 1);
				elementList.add(nextObject);
			}
		} else {
			throw new IllegalArgumentException("presortion '" + preSort + "' undefined.");
		}
	}

	@Override
	public void createInitialList(String preSort, int size, long randomSeed) throws Exception {
		this.elementList = new ArrayList<ObjectInterface>();
		
		if (preSort.toLowerCase().equals("random")){
			Random ran = new Random(randomSeed);
			for (int i = 0; i < size; i++) {
				SortObject nextObject = new SortObject();
				nextObject.setId(ran.nextInt(size)); 
				elementList.add(nextObject);
			}
		} else {
			this.createInitialList(preSort, size);
		}
	}
	
	@Override
	public List<ObjectInterface> getResult() {
		// TODO Auto-generated method stub
		return null;
	}
	
	public ObjectInterface get(int index) {
		return elementList.get(index);
	}
	
	public void set(int index, ObjectInterface newElement){
		try {
			elementList.set(index, newElement);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public void start () {
		
	}
	
	public boolean checkResult() {
		return true;
	}
	
	public void print() {
		boolean firstElement = true;
		for (int i = 0; i < elementList.size(); i++) {
			
			if (!firstElement)
				System.out.print(", ");
			
			System.out.print(elementList.get(i).getId());
			firstElement = false;
		}
		System.out.println();
	}
	
	public void print(List<ObjectInterface> elementList) {
		boolean firstElement = true;
		for (int i = 0; i < elementList.size(); i++) {
			
			if (!firstElement)
				System.out.print(", ");
			
			System.out.print(elementList.get(i).getId());
			firstElement = false;
		}
		System.out.println();
	}

	public void destroy() {
		elementList.clear();
		elementList = null;
	}
	
	////////////////////////////////////////////////////////////////

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<ObjectInterface> getElementList() {
		return elementList;
	}

	public void setElementList(List<ObjectInterface> elementList) {
		this.elementList = elementList;
	}
	
	////////////////////////////////////////////////////////////////
	
	protected void merge(List<ObjectInterface> A, int l, int m, int r) {
		List<ObjectInterface> left = new ArrayList<ObjectInterface>(m-l);
		List<ObjectInterface> right = new ArrayList<ObjectInterface>(r-m);
		//System.out.println("l: " + l);
		//System.out.println("m: " + m);
		//System.out.println("r: " + r);
		//System.out.println("A.size: " + A.size());
		
		//System.out.println("linke liste bauen");
		for(int i = l; i <= m ; i++) {
		//	System.out.println("index i: " + i);
		    left.add(A.get(i));
		}
		//System.out.print("linke liste: ");
		//print(left);
		
		//System.out.println("rechte liste bauen");
		for (int j = m + 1; j <= r; j++) {
		//	System.out.println("index j:" + j);
			right.add(A.get(j));
		}
		//System.out.print("rechte liste: ");
		//print(right);
		
		
		//System.out.println("Füge links und rechts zusammen");
		int leftIndex = 0, rightIndex= 0;
		for(int k = l; k <= r; k++) {
			if(right.size() == rightIndex) {
				A.set(k, left.get(leftIndex++));
			} else if (left.size() == leftIndex) {
				A.set(k, right.get(rightIndex++));
			} else if (right.get(rightIndex).getId() < left.get(leftIndex).getId()) {
				A.set(k, right.get(rightIndex++));
			} else {
				A.set(k, left.get(leftIndex++));
			}
		}
		//System.out.println("Teilsortierter zwischenschritt");
		//print();
	}
	

	@Override
	public void problemToConsole() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void problemToWindow() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void showResult() {
		boolean firstElement = true;
		for (int i = 0; i < elementList.size(); i++) {
			
			if (!firstElement)
				System.out.print(", ");
			
			System.out.print(elementList.get(i).getId());
			firstElement = false;
		}
		System.out.println();
		
	}
}
